package com.youlai.plan.service;

import cn.hutool.core.lang.Assert;
import com.youlai.common.model.Option;
import com.youlai.common.result.PageResult;
import com.youlai.core.security.model.SysUserDetails;
import com.youlai.common.base.PageBean;
import com.youlai.eng.query.BaseQuery;
import com.youlai.eng.query.PageQuery;
import com.youlai.plan.entity.PlanChargerSheetEntity;
import com.youlai.plan.repository.PlanChargerSheetRepository;
import com.youlai.system.service.SysDictService;
import com.youlai.system.util.SecurityUtils;
import com.youlai.utils.DateUtils;
import jakarta.annotation.Resource;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Query;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class PlanChargerSheetService {
    @Autowired
    private PlanChargerSheetRepository repository;

    @PersistenceContext
    private EntityManager em;

    public EntityManager getEntityManager() {
        return em;
    }

    @Resource
    SysDictService sysDictService;

    /**
     * 分页查询列表
     *
     * @param queryParams
     * @return
     */
    public Page<PlanChargerSheetEntity> getPage(PageQuery queryParams) {
        // 查询参数
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        String keywords = queryParams.getKeywords();
        DateUtils.toDatabaseFormat(queryParams, "startUpdateTime", "endUpdateTime");

        Sort sort =  Sort.by(Sort.Direction.DESC,"updateTime");   // .and(Sort.by("createTime").descending());
        Pageable pageable = PageRequest.of(pageNum-1, pageSize, sort);
        //动态查询
        Specification<PlanChargerSheetEntity> spec  = (Root<PlanChargerSheetEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(queryParams.getName())) {
                predicates.add(criteriaBuilder.like(root.get("name"), "%" + queryParams.getName() + "%"));
            }
            if (queryParams.getCode() != null) {
                predicates.add(criteriaBuilder.equal(root.get("code"), queryParams.getCode()));
            }

            if (queryParams.getStartUpdateTime() != null && queryParams.getEndUpdateTime() != null) {
                Date StartUpdateTimeDate = DateUtils.strToDateLong(queryParams.getStartUpdateTime());
                Date endUpdateTimeDate = DateUtils.strToDateLong(queryParams.getEndUpdateTime());
                predicates.add(criteriaBuilder.between(root.get("updateTime"), StartUpdateTimeDate, endUpdateTimeDate));
            }
            //查询发送成功并且未删除的
            predicates.add(criteriaBuilder.equal(root.get("deleted"), 0));
            Predicate predicate = criteriaBuilder.and(predicates.toArray(new  Predicate[predicates.size()]));

            if (StringUtils.isNotBlank(queryParams.getKeywords())) {
                Predicate predicateOr =  criteriaBuilder.or(
                    criteriaBuilder.equal(root.get("empNo"), queryParams.getKeywords()),
                    criteriaBuilder.equal(root.get("empName"), queryParams.getKeywords())
                );
                predicate = criteriaBuilder.and(predicate, predicateOr);
            }
            return predicate;
        };
        Page<PlanChargerSheetEntity> page = repository.findAll(spec, pageable);
        return page;
    }

    /**
     * 分页查询列表
     *
     * @param queryParams
     * @return
     */
    public PageResult<PlanChargerSheetEntity> getPageByHql(PageQuery queryParams) {
        // 查询参数
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        String keywords = queryParams.getKeywords();

        // 动态拼接sql
        String hql = "from PlanChargerSheetEntity t where 1=1 and deleted = 0 ";
        if (StringUtils.isNotEmpty(keywords)  ) {
            hql += " and (" +
                    " customerNo like '%" + keywords +"%' " +
                    " or shippingNo like '%" + keywords +"%' " +
                    ") ";
        }
        DateUtils.toDatabaseFormat(queryParams, "startUpdateTime", "endUpdateTime");
        if (StringUtils.isNotEmpty(queryParams.getStartUpdateTime())) {
            hql += " and DATE_FORMAT(updateTime, '%Y-%m-%d %H:%i:%s') >=  '"+ queryParams.getStartUpdateTime()  +"'  ";
        }
        if (StringUtils.isNotEmpty(queryParams.getEndUpdateTime())) {
            hql += " and DATE_FORMAT(updateTime, '%Y-%m-%d %H:%i:%s') <=  '"+ queryParams.getEndUpdateTime()  +"'  ";
        }
        hql += " and deleted = 0 ";

        // 查询数据
        PageBean pageBean = new PageBean();
        pageBean.setPage(pageNum);
        pageBean.setRows(pageSize);
        String countHql = getCountHql(hql);
        Query countQuery = em.createQuery(countHql);
        pageBean.setTotal(countQuery.getSingleResult().toString());

        hql += " order by  updateTime desc";
        Query query = em.createQuery(hql);
        query.setFirstResult(pageBean.getStartIndex());
        query.setMaxResults(pageBean.getRows());
        List<PlanChargerSheetEntity> list = query.getResultList();
        PageResult page = PageResult.success(list, pageBean.getTotal());
        return page;
    }

    public String getCountHql(String hql) {
        //hql = "from Book where bookName like :bookName"
        //hql = " select * from new Book where(bid,bookName) where bookName like :bookName"
        int index = hql.toUpperCase().indexOf("FROM");
        return "select count(1) " +hql.substring(index);
    }

    public void save(PlanChargerSheetEntity entity){
        // 校验员工编号是否存在
        String itemNo = entity.getPmoItemNo();
        Specification<PlanChargerSheetEntity> spec  = (Root<PlanChargerSheetEntity> root, CriteriaQuery<?> cq, CriteriaBuilder cb) -> {
            Predicate predicate = cb.and(cb.equal(root.get("itemNo"), itemNo));
            return predicate;
        };
        long count = repository.count(spec);
        Assert.isTrue(count == 0, "生产订单号已存在");

        SysUserDetails user = SecurityUtils.getUser();
        entity.setCreateBy(user.getUserId());
        entity.setCreateName(user.getUsername());
        entity.setUpdateBy(user.getUserId());
        entity.setUpdateName(user.getUsername());
        repository.save(entity);
    }

    public void update(PlanChargerSheetEntity entity){
        // 校验员工编号是否存在
        String itemNo = entity.getPmoItemNo();
        Specification<PlanChargerSheetEntity> spec  = (Root<PlanChargerSheetEntity> root, CriteriaQuery<?> cq, CriteriaBuilder cb) -> {
            Predicate predicate = cb.and(cb.equal(root.get("itemNo"), itemNo));
            predicate = cb.and(cb.notEqual(root.get("saleItemId"), entity.getPlanChargerSheetId()),predicate);
            return predicate;
        };
        long count = repository.count(spec);
        Assert.isTrue(count == 0, "地址编号已存在");

        SysUserDetails user = SecurityUtils.getUser();
        entity.setUpdateBy(user.getUserId());
        entity.setUpdateName(user.getUsername());
        repository.save(entity);
    }

    public PlanChargerSheetEntity findById(Long id){
        Optional<PlanChargerSheetEntity> optional  = repository.findById(id);
        if(optional.isPresent()) {
            return optional.get();
        }
        return null;
    }


    public List<PlanChargerSheetEntity> findListBy(PlanChargerSheetEntity entity){
        // 动态拼接sql
        String hql = "select * from PlanChargerSheetEntity where 1=1";
        if (StringUtils.isNotEmpty(entity.getPmoItemNo())  ) {
            hql += " and customerNo like '%" + entity.getPmoItemNo() +"%'";
        }
        hql += "  ";

        // 查询数据
        Query query = em.createQuery(hql);
        //List<Object[]> objArray = query.getResultList(); // 根据返回的结果来定义接收数据类型(对象,集合,基本数据类型等)，我这里查询统计数据，所以 list<Object[]>  接收,下方有示例代码
        List<PlanChargerSheetEntity> list = query.getResultList();
        return list;
    }

    public Boolean deleteAllById(String idStrs){
        SysUserDetails user = SecurityUtils.getUser();
        // 逻辑删除
        List<Long> ids = Arrays.asList(idStrs.split(",")).stream()
                .map(idStr -> Long.parseLong(idStr)).collect(Collectors.toList());
        for(Long id:ids) {
            Optional<PlanChargerSheetEntity> optional  = repository.findById(id);
            if(optional.isPresent()) {
                PlanChargerSheetEntity entity = optional.get();
                entity.setDeleted(1);

                entity.setUpdateBy(user.getUserId());
                entity.setUpdateName(user.getUsername());
                repository.save(entity);
            }
        }
        return true;
    }

    public List<Option> listEngEmpOptions(BaseQuery baseQuery) {
        Specification<PlanChargerSheetEntity> spec  = (Root<PlanChargerSheetEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) -> {
            Predicate predicate = cb.and(cb.equal(root.get("status"), 1));
            predicate = cb.and(cb.equal(root.get("deleted"), 0), predicate);
            return predicate;
        };
        List<PlanChargerSheetEntity> list = repository.findAll(spec);
        List<Option> lastList = new ArrayList<>();
        for(PlanChargerSheetEntity o:list) {
            Option option = new Option<String>();
            option.setLabel(o.getPmoItemNo());
            option.setValue(o.getPmoItemNo());
            lastList.add(option);
        }
        return lastList;
    }
}


